#!/usr/bin/ksh

#########################################################################
#									#
# Name:		mkpkg.tarp (Shell script)				#
#									#
# Completed:	26th August, 2003.					#
#									#
# Updated:	27th September, 2005.					#
#									#
# Author:	Simon Edwards, Proprius Consulting Ltd.			#
#									#
# Arguments:	-V		Print codemgr compatibility - currently	#
#				1.					#
#									#
# Arguments:	-r rel [-x cfg] [-v] [-f]				#
#		-r		Indicate the number of the release to	#
#				create - assigned by the 		#
#				mkpkg wrapper script usually.		#
#		-x		Specify an alternative cfg file - 	#
#				the default will be "cfg".		#
#		-f		Force create - if a version of this	#
#				release already exists it should be	#
#				over-written.				#
#									#
# Purpose:	This creates takes the information for the current	#
#		project and creates a tarp package for it. It does 	#
#		this using the information taken from the RELMGR_CONF	#
#		file and also the configuration file used for packing	#
#		itself - found typically in the pkg/cfg file.		#
#									#
#		This script does not check that all source code is	#
#		checked it - that is the business of the mkpkg wrapper	#
#		script.							#
#									#
#		A TARP package is a tar file that			#
#		has all files stored in relative positions to the	#
#		absolute install path - for example ./usr/bin/file	#
#		to install /usr/bin/file.				#
#									#
#		The tar file also includes a file called spec -		#
#		which is basically a text file with the following	#
#		lines in it:						#
#									#
#		NAME:pkg name						#
#		DESCRIPTION:pkg desription				#
#		VERSION:version of package				#
#		VENDOR:vendor (default is N/A)				#
#		LICENSE:license (default is GPL)			#
#		ROOTDIR:/ (default if not present)			#
#		POSTINSTALL:true|false  [stored as postinstall]		#
#		POSTREMOVE:true|false   [stored as postremove]		#
#		PREREMOVE:true|false	[stored as preremove]		#
#		PREINSTALL:true|false	[stored as preinstall]		#
#		DEPENDENCIES:pkg,version:...				#
#									#
#		The install_tarp uses the spec file to determine how	#
#		to install the files after uppacking them to a 		#
#		temporary directory.					#
#									#
#		See the install_tarp program for details on how this	#
#		works, along with backing up overwritten files,		#
#		having a release database etc.				#
#									#
# Limitations:	1 - Tarp is a limited simple packager, but should	#
#		    work across multiple UNIX vendors.			#
#									#
# Environment:	RELMGR_CFG	- Defines the file name containing the	#
#				  configuration settings for the 	#
#				  release manager for this user.	#
#									#
# Exit Codes:	0  - Package created successfully / all files in 	#
#		     version control system.				#
#		>1 - An error has occurred / not all files under 	#
#		     version control are checked back in.		#
# 									#
# Version:	@(#)1.1 Original (SE)>					#
# 		@(#)1.2 Correct -x and FINAL_DEPOT usage (SE)>		#
# 		@(#)1.3 Bug correction in tppkg routine searching (SE)> #
# 		@(#)1.4 Bug correction in tppkg routine searching (SE)> #
# 		@(#)1.5 Correct output handling of tppkg (SE)>		#
# 		@(#)1.6 Changed handling of spool depot (SE)>		#
#									#
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
#									#
# Complete RCS Version History						#
#									#
# Version:	1.5							#
# Date:		5th February, 2004.					#
# Author:	Simon Edwards, Proprius Consulting Ltd.			#
# Change:	When looking for the name of the package that was 	#
#		built it uses a more generic search since the output	#
#		from tppkg recently changed and the old method		#
#		broke.							#
#									#
# Version:	1.4							#
# Date:		23rd September, 2003.					#
# Author:	Simon Edwards, Proprius Consulting Ltd.			#
# Change:	Make use of BUILD_DEPOT is the DEPOT option is missing	#
#		which is the standard used for other packaging formats.	#
#		Also copy the package to FINAL_DEPOT on success.	#
#									#
# Version:	1.3							#
# Date:		23rd September, 2003.					#
# Author:	Simon Edwards, Proprius Consulting Ltd.			#
# Change:	We check to ensure that the tppkg can be found		#
#		using which - we also need to check that the number	#
#		of words returned is 1, otherwise the standard output	#
#		is actually an error...					#
#									#
# Version:								#
# Date:									#
# Author:								#
# Change:								#
#									#
#########################################################################

function logmsg
{
	[[ $ARG_verbose -eq 0 ]] && return
	print "MSG  : $1"
}

function logwarn
{
	print "WARN : $1"
}

function logerr
{
	print -u2 "ERROR: $1"
	[[ -n "$2" ]] && exit $2
}

SCRIPT=$(basename $0)
function loadvar 
{
	#################################################################
	# If we do not currently have a pkg directory, then create one!	#
	#################################################################

	[[ ! -d $1/pkg ]] && {
		mkdir -p $1/pkg 2>/dev/null || {
			logerr "Unable to create pkg directory" 2;
		}
		logwarn "Pkg directory auto-created!";
	}

	[[ ! -f $1/pkg/$CFGFILE ]] && {
		logerr "Configuration file \"$1/pkg/$CFGFILE\" does not exist." 5;
	}
	if [[ -n "$3" && "$3" = m ]]
	then
		( . $1/pkg/$CFGFILE 2>/dev/null; eval print \$$2 )
	elif [[ -n "$3" && "$3" = s ]]
	then
		awk -v searchfor="$2" '$1 == "#" {next} $1 ~ searchfor {split($0,a,"="); if(substr(a[1],1,length(searchfor)) == searchfor) { printf("%s %s\n",a[1],a[2]);exit(0);}}' \
		$1/pkg/$CFGFILE
	else
		awk -v searchfor="$2" '$1 == "#" {next} $1 ~ searchfor {split($0,a,"="); if(substr(a[1],1,length(searchfor)) == searchfor) { printf("%s %s\n",a[1],a[2]);}}' \
		$1/pkg/$CFGFILE
	fi
	return 0
}

function usage
{
	print -u2 "Usage: $SCRIPT -r release [-f] [-v]

Written by Simon Edwards 2000 - 2003, proprius.co.uk.
Please see the codemgr_$SCRIPT(1) manual page for more details.
"
exit 1
}

[[ -z "$RELMGR_CFG" ]] && {
	logerr "Variable \"RELMGR_CFG\" is not defined." 10;
}

[[ ! -f "$RELMGR_CFG" ]] && {
	logerr "\"RELMGR_CFG\" setting ($RELMGR_CFG) is not valid." 11;
}

whoami=$(whoami)

#########################################################################
# Now source the configuration information...				#
#########################################################################

. $RELMGR_CFG

export PROJECT_PREFIX PROJECT_PKGDIR PROJECT_RELDB PKG_TYPE VCTYPE
export DEFAULT_GROUP DEFAULT_PERMS DEFAULT_OWNER IGNORE_SUFFIXES
export FINAL_DEPOT
#########################################################################
# If the wrapper has been to generate the package it will have set the	#
# BUILD_IN_TMP variable, which now becomes the PROJECT_PREFIX for this	#
# particular package build.						#
#########################################################################

if [[ -n "$BUILD_IN_TMP" && -d $BUILD_IN_TMP ]]
then
	logmsg "PROJECT_PREFIX modified to $BUILD_IN_TMP"
	PROJECT_PREFIX=$BUILD_IN_TMP
fi

#########################################################################
# Now we have the basic details we need to parse the command line	#
# arguments to ensure everything looks ok.				#
#########################################################################

VERSION=0
FORCE=0
RELEASE=""
ARG_verbose=0
CFGFILE=""

while getopts ":Vfvr:x:" argval
do
	case $argval in
		V)	VERSION=1		;;
		f)	FORCE=1			;;
		v)	ARG_verbose=1		;;
		x)	CFGFILE=$OPTARG		;;
		r)	RELEASE=$OPTARG		;;
		*)	usage
	esac
done

if [[ $VERSION = 1 ]]
then
	print 1
	exit 0
fi

[[ -z "$CFGFILE" ]] && CFGFILE=cfg
[[ -z "$RELEASE" ]] && usage

#########################################################################
# We now work out the current product name, using the current directory	#
# path as a starting point. If the current directory path is not	#
# path of the PROJECT_PREFIX then we need to raise an error.		#
#########################################################################

project_name=$(print $PWD|
	awk -v projs=$PROJECT_PREFIX '{if(substr($1,1,length(projs))!=projs) exit(0);
		split(substr($1,2+length(projs)),a,"/");
		print a[1];}')

if [[ -z "$project_name" ]]
then
	logerr "Current path is invalid for a project!"
	logerr "Path must be sub-directory of \"$PROJECT_PREFIX\"." 12
fi

logmsg "Project name ascertained to be: $project_name"
pkg_name=$(loadvar $PROJECT_PREFIX/$project_name NAME|awk '{print $2}')

if [[ -n "$pkg_name" && "$CFGFILE" != cfg ]]
then
	logmsg "Building package: $pkg_name"
else
	pkg_name=$project_name
fi

logmsg "Project source tree named as: $project_name"

#########################################################################
# We now see if we can called the tppkg routine to handle the		#
# packaging - we expect it to be installed in /usr/local/bin/tppkg,	#
# /usr/bin/tppkg or /usr/local/tarp/bin/tppkg or TPPKG			#
#########################################################################

tppkg=""
[[ -n "$TPPKG" && -x $TPPKG && -f $TPPKG ]] && tppkg=$TPPKG
xxx="$(which tppkg 2>/dev/null)" && tppkg=$xxx
if [[ $(print $xxx | wc -w) -ne 1 ]]
then
	tppkg=""
fi

[[ -z "$tppkg" && -x /usr/local/bin/tppkg ]] && tppkg=/usr/local/bin/tppkg
[[ -z "$tppkg" && -x /usr/bin/tppkg ]] && tppkg=/usr/bin/tppkg
[[ -z "$tppkg" && -x /usr/local/tarp/bin/tppkg ]] && tppkg=/usr/local/tarp/bin/tppkg

[[ -z "$tppkg" ]] &&
	logerr "Unable to find \"tppkg\" command - aborting" 5

logmsg "Defined tppkg as $tppkg"

cd $PROJECT_PREFIX/$project_name
pkg_depot=$(loadvar $PROJECT_PREFIX/$project_name DEPOT.TARP s|awk '{print $2}')
[[ -z "$pkg_depot" ]] &&
	pkg_depot=$(loadvar $PROJECT_PREFIX/$project_name DEPOT s|awk '{print $2}')

[[ -z "$pkg_depot" && -n "$BUILD_DEPOT" ]] &&
	pkg_depot="$BUILD_DEPOT" &&
	logmsg "DEPOT not set - defaulting to $BUILD_DEPOT"

[[ -z "$pkg_depot" ]] && {
	logmsg "DEPOT not set - defaulting to /tmp for Tarp package.";
	pkg_depot=/tmp;
}

$tppkg -c pkg/$(basename $CFGFILE)  -r $RELEASE -d $pkg_depot $( [[ $ARG_verbose -eq 1 ]] && printf -- "-v" ) $( [[ $FORCE -eq 1 ]] && printf -- "-f" ) | tee /tmp/mkpkg.2.$$

ll=$(awk '$3=="Package" && $5=="built" {print $4;exit;}' /tmp/mkpkg.2.$$)
rm -f /tmp/mkpkg.2.$$

if [[ -f $pkg_depot/$ll ]]
then
	logmsg "Successfully built package in $pkg_depot"
	if [[ -n "$FINAL_DEPOT" && "$FINAL_DEPOT" != "$pkg_depot" ]]
	then
		cp $pkg_depot/$ll $FINAL_DEPOT 2>/dev/null
		if [[ $? -eq 0 ]]
		then
			logmsg "Copied package $ll to depot $FINAL_DEPOT successfully."
		else
			logerr "Unable to copy $ll to depot $FINAL_DEPOT." 22
		fi
	fi
else
	logerr "Unable to build package in $pkg_depot" 13
fi
exit 0
